package com.hk.commons.expression;

import org.springframework.context.expression.AnnotatedElementKey;
import org.springframework.context.expression.CachedExpressionEvaluator;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author Kevin
 * @date 2022/11/14 23:46
 */
public class MethodCachedExpressionEvaluator extends CachedExpressionEvaluator {

    private final Map<ExpressionKey, Expression> valueCache = new ConcurrentHashMap<>(64);

    /**
     * 基于方法的注解 表达式计算
     *
     * @param method          目标方法
     */
    public Object evaluate(String valueExpression, Method method, EvaluationContext evalContext) {
        return getExpression(this.valueCache, new AnnotatedElementKey(method, method.getDeclaringClass()), valueExpression)
                .getValue(evalContext);
    }

    /**
     * 基于方法的注解 表达式计算
     *
     * @param method          目标方法
     */
    public <T> T evaluate(String valueExpression, Method method, EvaluationContext evalContext, Class<T> clazz) {
        return getExpression(this.valueCache, new AnnotatedElementKey(method, method.getDeclaringClass()), valueExpression)
                .getValue(evalContext, clazz);
    }

    /**
     * 基于类的注解 表达式计算
     *
     * @param annotatedElementClass 目标类
     */
    public <T> T evaluate(String valueExpression, Class<?> annotatedElementClass, EvaluationContext evalContext, Class<T> clazz) {
        return getExpression(this.valueCache, new AnnotatedElementKey(annotatedElementClass, null), valueExpression)
                .getValue(evalContext, clazz);
    }
}
